// 节流
export const throttle = (func, wait = 500, immediate = true) => {
  if (immediate) {
    if (!flag) {
      flag = true;
      // 如果是立即执行，则在wait毫秒内开始时执行
      typeof func === 'function' && func();
      timer = setTimeout(() => {
        flag = false;
      }, wait);
    }
  } else {
    if (!flag) {
      flag = true
      // 如果是非立即执行，则在wait毫秒内的结束处执行
      timer = setTimeout(() => {
        flag = false
        typeof func === 'function' && func();
      }, wait);
    }

  }
}

// 防抖
let timeout = null;
/**
 * 防抖原理：一定时间内，只有最后一次操作，再过wait毫秒后才执行函数
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行 
 * @return null
 */
export const debounce = (func, wait = 500, immediate = false) => {
  // 清除定时器
  if (timeout !== null) clearTimeout(timeout);
  // 立即执行，此类情况一般用不到
  if (immediate) {
    var callNow = !timeout;
    timeout = setTimeout(function () {
      timeout = null;
    }, wait);
    if (callNow) typeof func === 'function' && func();
  } else {
    // 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
    timeout = setTimeout(function () {
      typeof func === 'function' && func();
    }, wait);
  }
}

// 控制台打印
const log = {}
/**
 * @description 返回这个样式的颜色值
 * @param {String} type 样式名称 [ primary | success | warning | danger | text ]
 */
function typeColor(type = 'default') {
  let color = ''
  switch (type) {
    case 'default': color = '#35495E'; break
    case 'primary': color = '#3488ff'; break
    case 'success': color = '#43B883'; break
    case 'warning': color = '#e6a23c'; break
    case 'danger': color = '#f56c6c'; break
    default: ; break
  }
  return color
}
/**
 * @description 打印一个 [ title | text ] 样式的信息
 * @param {String} title title text
 * @param {String} info info text
 * @param {String} type style
 */
log.capsule = function (title, info, type = 'primary') {
  console.log(
    `%c ${title} %c ${info} %c`,
    'background:#35495E; padding: 1px; border-radius: 3px 0 0 3px; color: #fff;',
    `background:${typeColor(type)}; padding: 1px; border-radius: 0 3px 3px 0;  color: #fff;`,
    'background:transparent'
  )
}
/**
 * @description 打印彩色文字
 */
log.colorful = function (textArr) {
  console.log(
    `%c${textArr.map(t => t.text || '').join('%c')}`,
    ...textArr.map(t => `color: ${typeColor(t.type)};`)
  )
}
/**
 * @description 打印 default 样式的文字
 */
log.default = function (text) {
  log.colorful([{ text }])
}
/**
 * @description 打印 primary 样式的文字
 */
log.primary = function (text) {
  log.colorful([{ text, type: 'primary' }])
}
/**
 * @description 打印 success 样式的文字
 */
log.success = function (text) {
  log.colorful([{ text, type: 'success' }])
}
/**
 * @description 打印 warning 样式的文字
 */
log.warning = function (text) {
  log.colorful([{ text, type: 'warning' }])
}
/**
 * @description 打印 danger 样式的文字
 */
log.danger = function (text) {
  log.colorful([{ text, type: 'danger' }])
}
export const Log = log;

// 数据
// 判断arr是否为一个数组，返回一个bool值
const isArray = arr => Object.prototype.toString.call(arr) === '[object Array]';
// 深度克隆
export const deepClone = obj => {
  if ([null, undefined, NaN, false].includes(obj)) return obj;
  if (typeof obj !== "object" && typeof obj !== 'function') return obj;
  const o = isArray(obj) ? [] : {};
  for (let i in obj) {
    if (obj.hasOwnProperty(i)) {
      o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
    }
  }
  return o;
}

// 返回随机数
export const random = (min = 0, max = 100) => {
  if (min >= 0 && max > 0 && max >= min) {
    const gab = max - min + 1;
    return Math.floor(Math.random() * gab + min);
  } else {
    return 0;
  }
}
// 数组打乱顺序
export const randomArray = (array = []) => {
  // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
  return array.sort(() => Math.random() - 0.5);
}

// 判断是否为空
export const isEmpty = value => {
  switch (typeof value) {
    case 'undefined':
      return true;
    case 'string':
      if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
      break;
    case 'boolean':
      if (!value) return true;
      break;
    case 'number':
      if (0 === value || isNaN(value)) return true;
      break;
    case 'object':
      if (null === value || value.length === 0) return true;
      for (var i in value) {
        return false;
      }
      return true;
  }
  return false;
}
// 去空格
export const trim = (str, pos = 'both') => {
  if (pos == 'both') {
    return str.replace(/^\s+|\s+$/g, "");
  } else if (pos == "left") {
    return str.replace(/^\s*/, '');
  } else if (pos == 'right') {
    return str.replace(/(\s*$)/g, "");
  } else if (pos == 'all') {
    return str.replace(/\s+/g, "");
  } else {
    return str;
  }
}

// 返回当前数据类型  String   Number Boolean Function Array Object Date RegExp Math Undefined Null
export const getDataType = value => {
  return Object.prototype.toString.call(value).slice(8, -1);
}
// 返回url参数
export const getQueryVariable = variable =>{
  const query = window.location.search.substring(1);
  const vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if(pair[0] == variable) return pair[1]
  }
  return(false);
}
// 数字格式化
export const formatNumber = (number = 0, places = 2, thousand = '', symbol = '', decimal = '.') => {
	const negative = number < 0 ? '-' : '',
		i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + '';
	let j = (j = i.length) > 3 ? j % 3 : 0;
	return symbol + negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : '');
}
// 数组对象排序  [{a:'asas',b:2},{a:'as',b:0}].sort(createComparator('b'))
export const createComparator = property => {
  return (object1,object2) => {
    const value1 = Number(object1[property]);
    const value2 = Number(object2[property]);
    if(value1 < value2 ){
        return -1;
    }else if(value1> value2 ){
        return 1;
    }else{
        return 0;
    }
  }
}
// 时间
// 时间日期格式化 y - 年 M -月 d- 日 h - 时 m - 分 s - 秒  
// yyyy:MM:dd|yyyy:MM|yyyy年MM月dd日|yyyy年MM月dd日 hh时mm分等,可自定义组合
export const timeFormat = (timestamp = null, fmt = 'yyyy-MM-dd hh:mm:ss') => {
  timestamp = parseInt(timestamp);
  // 如果为null,则格式化当前时间
  if (!timestamp) timestamp = Number(new Date());
  // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
  if (timestamp.toString().length == 10) timestamp *= 1000;
  let date = new Date(timestamp);
  let ret;
  let opt = {
    "y+": date.getFullYear().toString(), // 年
    "M+": (date.getMonth() + 1).toString(), // 月
    "d+": date.getDate().toString(), // 日
    "h+": date.getHours().toString(), // 时
    "m+": date.getMinutes().toString(), // 分
    "s+": date.getSeconds().toString() // 秒
  };
  for (let k in opt) {
    ret = new RegExp("(" + k + ")").exec(fmt);
    if (ret) {
      fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
    };
  };
  return fmt;
}
// 时间戳转 多久之前
export const timeFrom = (timestamp = null, format = 'yyyy-MM-dd') => {
  if (timestamp == null) timestamp = Number(new Date());
  timestamp = parseInt(timestamp);
  // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
  if (timestamp.toString().length == 10) timestamp *= 1000;
  var timer = (new Date()).getTime() - timestamp;
  timer = parseInt(timer / 1000);
  // 如果小于5分钟,则返回"刚刚",其他以此类推
  let tips = '';
  switch (true) {
    case timer < 300:
      tips = '刚刚';
      break;
    case timer >= 300 && timer < 3600:
      tips = parseInt(timer / 60) + '分钟前';
      break;
    case timer >= 3600 && timer < 86400:
      tips = parseInt(timer / 3600) + '小时前';
      break;
    case timer >= 86400 && timer < 2592000:
      tips = parseInt(timer / 86400) + '天前';
      break;
    default:
      // 如果format为false，则无论什么时间戳，都显示xx之前
      if (format === false) {
        if (timer >= 2592000 && timer < 365 * 86400) {
          tips = parseInt(timer / (86400 * 30)) + '个月前';
        } else {
          tips = parseInt(timer / (86400 * 365)) + '年前';
        }
      } else {
        tips = timeFormat(timestamp, format);
      }
  }
  return tips;
}
// 秒格式化
export const secondToDate = (msd) => {
  var time = msd
  if (time != null && time != '') {
    if (time > 60 && time < 60 * 60) {
        time = parseInt(time / 60.0) + '分' + parseInt((parseFloat(time / 60.0) -
            parseInt(time / 60.0)) * 60) + '秒';
    } else if (time >= 60 * 60 && time < 60 * 60 * 24) {
        time = parseInt(time / 3600.0) + '时' + parseInt((parseFloat(time / 3600.0) -
            parseInt(time / 3600.0)) * 60) + '分' +
            parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
                parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60) + '秒';
    } else if (time >= 60 * 60 * 24) {
        time = parseInt(time / 3600.0 / 24) + '天' + parseInt((parseFloat(time / 3600.0 / 24) -
            parseInt(time / 3600.0 / 24)) * 24) + '时' + parseInt((parseFloat(time / 3600.0) -
            parseInt(time / 3600.0)) * 60) + '分' +
            parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
                parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60) + '秒';
    } else {
        time = parseInt(time) + '秒';
    }
  }
  return time;
}
// 返回当前日期的前 n 天的时间戳 默认前 30天
export const getPrevTimer = (n = 30) => {
  const nowTime = new Date().getTime()
  const prevTime = 1000 * 60 * 60 * 24 * n
  return nowTime - prevTime
}
// 字符串复制到粘贴板
export const execCommand = str => {
  return new Promise((resolve, reject) => {
    const body = document.getElementsByTagName('body')[0]
    const input = document.createElement('input')
    input.value = str
    input.disabled = false
    body.appendChild(input)
    input.select()
    try{
      if(document.execCommand("Copy","false",null)){
        resolve(true)
      }else{
        resolve(false)
      }
    }catch(err){
      resolve(false)
    }
    body.removeChild(input)
  })
}
// 数组去重 单个参数去重  两个 合并数组去重 返回新数组
export const distinct = (a, b) => {
  const arr = a.concat(b)
  let result = []
  let obj = {}
  for (let i of arr) {
    if (!obj[i]) {
      result.push(i)
      obj[i] = 1
    }
  }
  return result
}

// 更新网站标题
export const changeTitle = titleText => {
  const processTitle = 'vuetify_admin'
  window.document.title = `${processTitle}${titleText ? ` | ${titleText}` : ''}`
}

// 判断当前环境
export const browserRedirect = () => {
  let result = ''
  const sUserAgent = navigator.userAgent.toLowerCase();
  const bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
  const bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
  const bIsMidp = sUserAgent.match(/midp/i) == "midp";
  const bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
  const bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
  const bIsAndroid = sUserAgent.match(/android/i) == "android";
  const bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
  const bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
  const weixin = sUserAgent.match(/micromessenger/i) == "micromessenger";
  if(weixin){
    result = 'weixin'
  } else if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM ) {
    result = 'phone'
  } else {
    result = 'pc'
  }
  return result
}
export const open = url => {
  var a = document.createElement('a')
  a.setAttribute('href', url)
  a.setAttribute('target', '_blank')
  a.setAttribute('id', 'admin-link-temp')
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(document.getElementById('admin-link-temp'))
}

// 生成下载 pdf
export const handleWindowPrint = (ele, fileName, vm)=>{
 
  var oIframe = document.createElement('iframe');
  var oScript = document.createElement('script');

  document.body.appendChild(oIframe);

  var titleText = document.head.getElementsByTagName('title')[0].innerText;
  document.head.getElementsByTagName('title')[0].innerText = `${fileName}`;

  oIframe.contentDocument.head.innerHTML = `<meta charset="utf-8">
                                            <title>${fileName}</title>
                                            <meta name="format-detection" content="telephone=no">
                                            <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                                            <meta name="viewport" content="width=device-width,initial-scale=1.0">`;

  // oIframe.contentWindow.document.body.innerHTML = document.querySelector(ele).outerHTML;
  oIframe.contentDocument.body.innerHTML = ele.outerHTML;
  oScript.innerHTML = 'window.print();';
  oIframe.contentDocument.body.appendChild(oScript);
  document.body.removeChild(oIframe);
  document.head.getElementsByTagName('title')[0].innerText = titleText;
};


export const isExternal = (path) => {
  return /^(https?:|mailto:|tel:)/.test(path)
}